﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;

namespace NuIoc.Tests
{
    public class Boo
    {

    }

    public interface IFoo
    {

    }

    public class Foo : IFoo
    {

    }

    public interface IService
    {
        IDependentService DependentService { get; }
    }

    public class Service : IService
    {
        public Service(IDependentService dependentService)
        {
            DependentService = dependentService;
        }

        [Inject]
        public IDependentService DependentService
        {
            get;
            private set;
        }
    }

    public interface IDependentService
    {

    }

    public class DependentService : IDependentService
    {

    }

    public interface IHop
    {
        Bob Bob { get; }
    }

    public class Hop : IHop
    {
        [Inject]
        public Bob Bob { get; internal set; }
    }

    public class Bob
    {

    }

    public class Bar
    {
        [Inject]
        public void Foo(IFoo foo)
        {
            Value = foo;
        }

        public IFoo Value { get; private set; }
    }

    [TestFixture]
    public class ContainerTest
    {
        [TestCase]
        public void RegisterConcrete()
        {
            IContainer container = new Container();

            container.Register<Boo>();

            Assert.IsTrue(container.IsRegistered<Boo>());

            var instance = container.Resolve<Boo>();
        }

        [TestCase]
        public void Register()
        {
            IContainer container = new Container();

            container.Register<IFoo, Foo>();

            Assert.IsTrue(container.IsRegistered<IFoo>());

            var instance = container.Resolve<IFoo>();
        }

        [TestCase]
        public void ConstructorInjection()
        {
            IContainer container = new Container();

            container.Register<IService, Service>();
            container.Register<IDependentService, DependentService>();

            var dependentService = container.Resolve<IDependentService>();
            var service = container.Resolve<IService>();

            Assert.IsNotNull(service.DependentService);
            Assert.AreEqual(service.DependentService, dependentService);
        }

        [TestCase]
        public void PropertyInjection()
        {
            IContainer container = new Container();

            container.Register<IHop, Hop>();
            container.Register<Bob>();

            var bob = container.Resolve<Bob>();
            var hop = container.Resolve<IHop>();

            Assert.IsNotNull(hop.Bob);
            Assert.AreEqual(hop.Bob, bob);
        }

        [TestCase]
        public void MethodInjection()
        {
            IContainer container = new Container();

            container.Register<IFoo, Foo>();
            container.Register<Bar>();

            var foo = container.Resolve<IFoo>();
            var bar = container.Resolve<Bar>();

            Assert.IsNotNull(bar.Value);
            Assert.AreEqual(bar.Value, foo);
        }
    }

  
}
